@TestOn('browser && !js')
library angular2.test.public_api_test;

import 'package:test/test.dart';

import 'symbol_inspector/symbol_inspector.dart';

// =============================================================================
// =============================================================================
// ============= S T O P   -    S T O P   -  S T O P   -  S T O P  =============
// =============================================================================
// =============================================================================
//
// DO NOT EDIT THIS LIST OF PUBLIC APIS UNLESS YOU GET IT CLEARED BY:
// mhevery, ferhat, or matanl!
//
// =============================================================================
// =============================================================================
var NG_COMMON = [
  'AbstractControl',
  'AbstractControlDirective',
  'AsyncPipe',
  'COMMON_DIRECTIVES',
  'COMMON_PIPES',
  'CORE_DIRECTIVES',
  'CheckboxControlValueAccessor',
  'Control',
  'ControlArray',
  'ControlContainer',
  'ControlGroup',
  'ControlValueAccessor',
  'CurrencyPipe',
  'DatePipe',
  'DecimalPipe',
  'DefaultValueAccessor',
  'FORM_BINDINGS',
  'FORM_DIRECTIVES',
  'FORM_PROVIDERS',
  'Form',
  'FormBuilder',
  'JsonPipe',
  'LowerCasePipe',
  'MaxLengthValidator',
  'MinLengthValidator',
  'NG_ASYNC_VALIDATORS',
  'NG_VALIDATORS',
  'NG_VALUE_ACCESSOR',
  'NgClass',
  'NgControl',
  'NgControlGroup',
  'NgControlName',
  'NgControlStatus',
  'NgFor',
  'NgForm',
  'NgFormControl',
  'NgFormModel',
  'NgIf',
  'NgTemplateOutlet',
  'NgModel',
  'NgSelectOption',
  'NgStyle',
  'NgSwitch',
  'NgSwitchWhen',
  'NgSwitchDefault',
  'NumberPipe',
  'ObservableListDiff',
  'ObservableListDiffFactory',
  'PatternValidator',
  'PercentPipe',
  'ReplacePipe',
  'RequiredValidator',
  'SelectControlValueAccessor',
  'SlicePipe',
  'UpperCasePipe',
  'Validator',
  'ValidatorFn',
  'Validators',
  'RadioButtonState',
  'NgLocalization',
  'NgPlural',
  'NgPluralCase'
];
var NG_COMPILER = [
  'TemplateAst',
  'TemplateAstVisitor',
  'DEFAULT_PACKAGE_URL_PROVIDER',
  'UrlResolver',
  'AttrAst',
  'BoundDirectivePropertyAst',
  'BoundElementPropertyAst',
  'BoundEventAst',
  'BoundTextAst',
  'COMPILER_PROVIDERS',
  'CompileDirectiveMetadata',
  'CompileInjectorModuleMetadata',
  'CompileTemplateMetadata',
  'CompileTypeMetadata',
  'DirectiveAst',
  'ElementAst',
  'EmbeddedTemplateAst',
  'NgContentAst',
  'PLATFORM_DIRECTIVES',
  'PLATFORM_PIPES',
  'PropertyBindingType',
  'SourceModule',
  'TextAst',
  'VariableAst',
  'ReferenceAst',
  'XHR',
  'templateVisitAll',
  'CompileDiDependencyMetadata',
  'CompileFactoryMetadata',
  'CompileIdentifierMetadata',
  'CompileMetadataWithIdentifier',
  'CompileMetadataWithType',
  'CompilePipeMetadata',
  'CompileProviderMetadata',
  'CompileQueryMetadata',
  'CompileTokenMetadata',
  'CompilerConfig',
  'RenderTypes',
  'DirectiveResolver',
  'NormalizedComponentWithViewDirectives',
  'OfflineCompiler',
  'PipeResolver',
  'ProviderAst',
  'ProviderAstType',
  'ViewResolver',
  'createOfflineCompileUrlResolver'
];
var NG_CORE = [
  'APP_INITIALIZER',
  'APP_ID',
  'AngularEntrypoint',
  'AbstractProviderError',
  'ApplicationRef',
  'APPLICATION_COMMON_PROVIDERS',
  'Attribute',
  'Provider',
  'PLATFORM_DIRECTIVES',
  'CollectionChangeRecord',
  'ChangeDetectionStrategy',
  'ChangeDetectorRef',
  'ComponentResolver',
  'Component',
  'ComponentState',
  'ComponentStateCallback',
  'ComponentRef',
  'ContentChild',
  'ContentChildren',
  'CyclicDependencyError',
  'PLATFORM_PIPES',
  'ReflectiveDependency',
  'DependencyMetadata',
  'Directive',
  'InjectorModule',
  'Provides',
  'ProviderProperty',
  'SkipAngularInitCheck',
  'DynamicComponentLoader',
  'ElementRef',
  'Output',
  'EmbeddedViewRef',
  'EventEmitter',
  'ExceptionHandler',
  'ExpressionChangedAfterItHasBeenCheckedException',
  'Host',
  'HostBinding',
  'HostListener',
  'ComponentFactory',
  'Inject',
  'Injectable',
  'Injector',
  'MapInjector',
  'MapInjectorFactory',
  'InjectorFactory',
  'ReflectiveInjector',
  'InstantiationError',
  'InvalidProviderError',
  'IterableDiffers',
  'ReflectiveKey',
  'KeyValueChangeRecord',
  'KeyValueDiffers',
  'NgZone',
  'NgZoneError',
  'NoAnnotationError',
  'NoProviderError',
  'OpaqueToken',
  'Optional',
  'OutOfBoundsError',
  'Pipe',
  'PlatformRef',
  'Input',
  'Query',
  'QueryList',
  'Renderer',
  'RootRenderer',
  'RenderComponentType',
  'ResolvedReflectiveBinding',
  'ResolvedReflectiveProvider',
  'ResolvedReflectiveFactory',
  'Self',
  'SkipSelf',
  'SimpleChange',
  'TemplateRef',
  'Testability',
  'TestabilityRegistry',
  'GetTestability',
  'PACKAGE_ROOT_URL',
  'View',
  'ViewChild',
  'ViewChildren',
  'ViewContainerRef',
  'ViewEncapsulation',
  'ViewQuery',
  'WrappedException',
  'WrappedValue',
  'provide',
  'createNgZone',
  'coreBootstrap',
  'coreLoadAndBootstrap',
  'createPlatform',
  'disposePlatform',
  'getPlatform',
  'PLATFORM_COMMON_PROVIDERS',
  'PLATFORM_INITIALIZER',
  'AfterContentChecked',
  'AfterContentInit',
  'AfterViewChecked',
  'AfterViewInit',
  'DoCheck',
  'IterableDifferFactory',
  'IterableDiffer',
  'KeyValueDifferFactory',
  'KeyValueDiffer',
  'OnChanges',
  'OnDestroy',
  'OnInit',
  'PipeTransform',
  'reflector',
  'Stream',
  'GetterFn',
  'MethodFn',
  'NoReflectionCapabilities',
  'PlatformReflectionCapabilities',
  'ReflectionInfo',
  'Reflector',
  'SetterFn',
  'ViewRef',
  'TrackByFn',
  'noValueProvided',
];
var NG_INSTRUMENTATION = [
  'wtfCreateScope',
  'wtfEndTimeRange',
  'wtfLeave',
  'WtfScopeFn',
  'wtfStartTimeRange'
];
var NG_PLATFORM_BROWSER = [
  'AngularEntrypoint',
  'BROWSER_APP_PROVIDERS',
  'BROWSER_PROVIDERS',
  'BROWSER_SANITIZATION_PROVIDERS',
  'SanitizationService',
  'TemplateSecurityContext',
  'BrowserDomAdapter',
  'CACHED_TEMPLATE_PROVIDER',
  'DOCUMENT',
  'Title',
  'bootstrap',
  'browserPlatform',
  'disableDebugTools',
  'enableDebugTools',
  'RUNTIME_COMPILER_PROVIDERS'
];
var NG_PLATFORM_BROWSER_TESTING = [
  'inspectNativeElement',
  'By',
  'DebugNode',
  'DebugElement',
  'CACHED_TEMPLATE_PROVIDER',
  'TEST_BROWSER_APPLICATION_PROVIDERS',
  'TEST_BROWSER_PLATFORM_PROVIDERS',
];
var NG_PLATFORM_COMMON = [
  'APP_BASE_HREF',
  'HashLocationStrategy',
  'Location',
  'LocationStrategy',
  'PathLocationStrategy',
  'PlatformLocation',
];

var NG_API = {
  commonLib: NG_COMMON,
  compilerLib: NG_COMPILER,
  coreLib: NG_CORE,
  instrumentationLib: NG_INSTRUMENTATION,
  platformBrowserLib: NG_PLATFORM_BROWSER,
  platformBrowserTestingLib: NG_PLATFORM_BROWSER_TESTING,
  platformCommonLib: NG_PLATFORM_COMMON,
};

void main() {
  group('Public API check', () {
    var publicLibraries = [
      commonLib,
      compilerLib,
      coreLib,
      instrumentationLib,
      platformBrowserLib,
      platformBrowserTestingLib,
      platformCommonLib,
    ];
    for (var lib in publicLibraries) {
      test('for ${lib} should fail when it changes unexpectedly', () {
        var symbols = getSymbolsFromLibrary(lib);
        expect(diff(symbols, NG_API[lib]), []);
      });
    }
  });
}

List<String> diff(List<String> actual, List<String> expected) {
  actual.sort();
  expected.sort();
  var missing =
      actual.where((i) => expected.indexOf(i) < 0).map((s) => '+${ s}');
  var extra = expected.where((i) => actual.indexOf(i) < 0).map((s) => '-${ s}');
  return <String>[]..addAll(missing)..addAll(extra);
}
